﻿@page "/diagram/shapes"

@using Syncfusion.Blazor.Diagrams
@using System.Collections.ObjectModel
@inherits SampleBaseComponent;

<SampleDescription>
    <p>  This sample illustrates basic built-in shapes, such as basic shapes and flow shapes.</p>
    <p style="font-weight: bold;">A new blazor diagram component which provides better performance than the existing diagram control in Blazor WebAssembly App. It is available in preview mode. Check the samples <a target='_blank' href='diagramcomponent/flowchart'>here</a>.</p>
</SampleDescription>
<ActionDescription>
   <p>This example shows how to define built-in shapes that are used to visualize geometric information, workflow, or business flow diagrams. The <a target='_blank' href='https://blazor.syncfusion.com/documentation/diagram/bpmn-shapes/bpmn-shapes/'>Type</a> property of the <a target='_blank' href='https://blazor.syncfusion.com/documentation/diagram/shapes/'>Shape</a> allows you to choose the type of shape.</p>
</ActionDescription>

    <div class="control-section">
        <SfDiagram ID="diagram" Height="790px" Nodes="@NodeCollection">
            <DiagramPageSettings>
                <DiagramFitOptions CanFit="true"></DiagramFitOptions>
            </DiagramPageSettings>
            <DiagramSnapSettings Constraints="@SnapConstraints.None"></DiagramSnapSettings>
        </SfDiagram>

    </div>

@code{
    

    public double length = 70;

    public ObservableCollection<DiagramNode> NodeCollection
    {
        get;
        set;
    }

    protected override void OnInitialized()
    {
        NodeCollection = new ObservableCollection<DiagramNode>();
        #region Basic Shapes
        AddShapeText("Basic Shapes", NodeConstraints.PointerEvents);
        AddBasicShapes("rectLabel", "Rectangle", BasicShapes.Rectangle,false);
        AddBasicShapes("ellipseLabel", "Ellipse", BasicShapes.Ellipse,true);
        AddBasicShapes("triLabel", "Triangle", BasicShapes.Triangle,true);
        AddBasicShapes("plusLabel", "Plus", BasicShapes.Plus,true);
        AddBasicShapes("starLabel", "Star", BasicShapes.Star,true);
        AddBasicShapes("pentLabel", "Pentagon", BasicShapes.Pentagon,true);
        AddBasicShapes("heptLabel", "Heptagon", BasicShapes.Heptagon,true);
        AddBasicShapes("octLabel", "Octagon", BasicShapes.Octagon,true);
        AddBasicShapes("trapLabel", "Trapezoid", BasicShapes.Trapezoid,false);
        AddBasicShapes("decLabel", "Decagon", BasicShapes.Decagon,true);
        AddBasicShapes("rightLabel", "Right Triangle", BasicShapes.RightTriangle,true);
        AddBasicShapes("paraLabel", "Parallelogram", BasicShapes.Parallelogram,true);
        #endregion

        #region FlowShapes
        AddShapeText("Flow Shapes", NodeConstraints.PointerEvents);
        AddFlowShapes("terminateLabel", "Terminator", FlowShapes.Terminator);
        AddFlowShapes("processLabel", "Process", FlowShapes.Process);
        AddFlowShapes("decisionLabel", "Decision", FlowShapes.Decision);
        AddFlowShapes("documentLabel", "Document", FlowShapes.Document);
        AddFlowShapes("preLabel", "Predefined Process", FlowShapes.PreDefinedProcess);
        AddFlowShapes("paperLabel", "Punched Tape", FlowShapes.PaperTap);
        AddFlowShapes("directLabel", "Direct Data", FlowShapes.DirectData);
        AddFlowShapes("seqLabel", "Sequential Data", FlowShapes.SequentialData);
        AddFlowShapes("sortLabel", "Sort", FlowShapes.Sort);
        AddFlowShapes("multiLabel", "Multidocument", FlowShapes.MultiDocument);
        AddFlowShapes("collateLabel", "Collate", FlowShapes.Collate);
        AddFlowShapes("summingLabel", "Summing Junction", FlowShapes.SummingJunction);
        AddFlowShapes("or", "Or", FlowShapes.Or);
        AddFlowShapes("internalLabel", "Internal Storage", FlowShapes.InternalStorage);
        AddFlowShapes("extractLabel", "Extract", FlowShapes.Extract);
        AddFlowShapes("manualLabel", "Manual Operation", FlowShapes.ManualOperation);
        AddFlowShapes("mergeLabel", "Merge", FlowShapes.Merge);
        AddFlowShapes("offLabel", "Off-page Reference", FlowShapes.OffPageReference);
        AddFlowShapes("seqAccess", "Sequential Access Storage", FlowShapes.SequentialAccessStorage);
        AddFlowShapes("dataLabel", "Data", FlowShapes.Data);
        AddFlowShapes("cardLabel", "Card", FlowShapes.Card);
        #endregion

        #region BpmnShapeModel
        AddShapeText("BPMN Shapes", NodeConstraints.PointerEvents);
        DiagramNodeAnnotation statEventAnnot = new DiagramNodeAnnotation() { Content = "Start Event", Id = "startLabel" };
        DiagramNode startEventNode = new DiagramNode()
        {
            Shape = new DiagramShape()
            {
                Type = Syncfusion.Blazor.Diagrams.Shapes.Bpmn,
                BpmnShape = BpmnShapes.Event,
                Event = new DiagramBpmnEvent() { Event = BpmnEvents.Start, Trigger = BpmnTriggers.None }
            },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { statEventAnnot }
        };
        NodeCollection.Add(startEventNode);
        DiagramNodeAnnotation interEventAnnot = new DiagramNodeAnnotation() { Content = "Intermediate Event", Id = "interLabel" };
        DiagramNode interEventNode = new DiagramNode()
        {
            Shape = new DiagramShape()
            {
                Type = Syncfusion.Blazor.Diagrams.Shapes.Bpmn,
                BpmnShape = BpmnShapes.Event,
                Event = new DiagramBpmnEvent() { Event = BpmnEvents.Intermediate, Trigger = BpmnTriggers.None }
            },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { interEventAnnot }
        };
        NodeCollection.Add(interEventNode);
        DiagramNodeAnnotation endEventAnnot = new DiagramNodeAnnotation() { Content = "End Event", Id = "endLabel" };
        DiagramNode endEventNode = new DiagramNode()
        {
            Shape = new DiagramShape()
            {
                Type = Syncfusion.Blazor.Diagrams.Shapes.Bpmn,
                BpmnShape = BpmnShapes.Event,
                Event = new DiagramBpmnEvent() { Event = BpmnEvents.End, Trigger = BpmnTriggers.None }
            },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { endEventAnnot }
        };
        NodeCollection.Add(endEventNode);
        AddBpmnShape("gatewayLabel", "Gateway", BpmnShapes.Gateway);
        DiagramNodeAnnotation taskAnnot = new DiagramNodeAnnotation() { Content = "Task", Id = "taskLabel" };
        DiagramNode taskNode = new DiagramNode()
        {
            Shape = new DiagramShape()
            {
                Type = Syncfusion.Blazor.Diagrams.Shapes.Bpmn,
                BpmnShape = BpmnShapes.Activity,
                Activity = new DiagramBpmnActivity() { Activity = BpmnActivities.Task }
            },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { taskAnnot }
        };
        NodeCollection.Add(taskNode);
        DiagramNodeAnnotation transactionAnnot = new DiagramNodeAnnotation() { Content = "Transaction", Id = "transactionLabel" };
        DiagramNode transactionNode = new DiagramNode()
        {
            Shape = new DiagramShape()
            {
                Type = Syncfusion.Blazor.Diagrams.Shapes.Bpmn,
                BpmnShape = BpmnShapes.Activity,
                Activity = new DiagramBpmnActivity()
                {
                    Activity = BpmnActivities.SubProcess,
                    SubProcess = new DiagramBpmnSubProcess()
                    {
                        Type = BpmnSubProcessTypes.Transaction,
                        Transaction = new DiagramBpmnTransactionSubProcess() { Success = new SuccessSubEvent() { Visible = false }, Failure = new FailureSubEvent() { Visible = false }, Cancel = new CancelSubEvent() { Visible = false } }
                    }
                }
            },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { transactionAnnot }
        };
        NodeCollection.Add(transactionNode);
        AddBpmnShape("messageLabel", "Message", BpmnShapes.Message);
        AddBpmnShape("dataObjectLabel", "Data Object", BpmnShapes.DataObject);
        AddBpmnShape("dataSourceLabel", "Data Source", BpmnShapes.DataSource);
        AddBpmnShape("groupLabel", "Group", BpmnShapes.Group);

        #endregion
        UpdateValues();
    }

    private void AddShapeText(string textContent, NodeConstraints constraints)
    {
        DiagramNode node = new DiagramNode()
        {
            Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Text, TextContent = textContent },
            Style = new NodeShapeStyle() { FontSize = 16, Fill = "None", FontFamily = "sans-serif", Bold = true, StrokeWidth = 0 },
            Constraints = constraints
        };
        NodeCollection.Add(node);
    }

    private void AddBasicShapes(string id, string shapeText, BasicShapes shapes,bool CheckAspectRatio)
    {
        DiagramNodeAnnotation nodeannotation = new DiagramNodeAnnotation() { Content = shapeText, Id = id };
        DiagramNode node = new DiagramNode()
        {

            Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Basic, BasicShape = shapes },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { nodeannotation }

        };
        if (CheckAspectRatio)
        {
            node.Constraints = node.Constraints | NodeConstraints.AspectRatio;
        }
        NodeCollection.Add(node);
    }

    private void AddFlowShapes(string id, string shapeText, FlowShapes shapes)
    {
        DiagramNodeAnnotation terminateAnnot = new DiagramNodeAnnotation() { Content = shapeText, Id = id };
        DiagramNode terminatNode = new DiagramNode()
        {
            Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Flow, FlowShape = shapes },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { terminateAnnot }
        };
        NodeCollection.Add(terminatNode);
    }

    private void AddBpmnShape(string id, string shapeText, BpmnShapes bpmn)
    {
        DiagramNodeAnnotation statEventAnnot = new DiagramNodeAnnotation() { Content = shapeText, Id = id };
        DiagramNode startEventNode = new DiagramNode()
        {
            Shape = new DiagramShape()
            {
                Type = Syncfusion.Blazor.Diagrams.Shapes.Bpmn,
                BpmnShape = bpmn
            },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { statEventAnnot }
        };
        NodeCollection.Add(startEventNode);
    }

    private void UpdateValues()
    {
        int offsetx = 60;
        int offsety = 50;
        int count = 1;

        for (int i = 0; i < NodeCollection.Count; i++)
        {
            DiagramNode node = NodeCollection[i];
            node.Width = 40;
            node.Height = 40;

            if (node.Shape.Type == Syncfusion.Blazor.Diagrams.Shapes.Flow)
            {
                FlowShapes shapeType = node.Shape.FlowShape;
                if (shapeType == FlowShapes.Process || shapeType == FlowShapes.Terminator)
                {
                    node.Height = 20;
                }
                else if (shapeType == FlowShapes.Decision)
                {
                    node.Height = 35;
                }
                else if (shapeType == FlowShapes.Document || shapeType == FlowShapes.DirectData ||
                  shapeType == FlowShapes.MultiDocument || shapeType == FlowShapes.PreDefinedProcess)
                {
                    node.Height = 30;
                }
            }

            if (node.Shape.Type != Syncfusion.Blazor.Diagrams.Shapes.Text)
            {
                if (node.Annotations.Count > 0)
                {
                    node.Annotations[0].VerticalAlignment = VerticalAlignment.Top;
                    node.Annotations[0].Offset = new NodeAnnotationOffset() { Y = 1 };
                    node.Annotations[0].Margin = new NodeAnnotationMargin() { Top = 10 };
                }
                node.OffsetX = offsetx;
                node.OffsetY = offsety;
                offsetx = offsetx + 90;
                if (count % 10 == 0)
                {
                    offsety = offsety + 100;
                    offsetx = 60;
                }
                count++;
            }

            if (node.Shape.Type == Syncfusion.Blazor.Diagrams.Shapes.Text)
            {
                offsetx = 60;
                node.OffsetX = offsetx;
                if (count > 1)
                {
                    offsety += 100;
                }
                node.OffsetY = offsety;
                offsety = offsety + 50;
                count = 1;
                node.Width = 150;
                node.Height = 50;
                node.OffsetX = 90;
                if (node.Shape.Content != null && node.Shape.Content.ToString() != "Basic Shapes")
                {
                    node.OffsetX = 90;
                    node.OffsetY = offsety + 50;
                    offsety = offsety + 100;
                }
            }
        }
    }
}
